package com.amumu.drama.common.modules.invitation.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.amumu.drama.common.base.api.CommonPage;
import com.amumu.drama.common.base.api.CommonResult;
import com.amumu.drama.common.constant.InvitationTypeEnum;
import com.amumu.drama.common.modules.invitation.dto.AnchorDto;
import com.amumu.drama.common.modules.invitation.dto.req.InvitationAnchorPageQuery;
import com.amumu.drama.common.modules.invitation.dto.resp.InvitationAnchorDetailResp;
import com.amumu.drama.common.modules.invitation.dto.resp.InvitationAnchorListResp;
import com.amumu.drama.common.modules.invitation.mapping.InvitationAnchorDetailRespMapping;
import com.amumu.drama.common.modules.invitation.mapping.InvitationAnchorListRespMapping;
import com.amumu.drama.common.modules.invitation.service.InvitationAnchorService;
import com.amumu.drama.common.modules.invitation.service.InvitationLogService;
import com.amumu.drama.common.modules.order.manager.OrderManager;
import com.amumu.drama.mapper.InvitationAnchorMapper;
import com.amumu.drama.mapper.OmsOrderMapper;
import com.amumu.drama.model.InvitationAnchor;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @Auther: DM
 * @Date: 2024/6/11 10:40
 * @Description:
 */
@Service
@Log4j2
public class InvitationAnchorServiceImpl extends ServiceImpl<InvitationAnchorMapper, InvitationAnchor> implements InvitationAnchorService {

    @Autowired
    private InvitationAnchorMapper invitationAnchorMapper;

    @Autowired
    private OrderManager orderManager;

    @Autowired
    private InvitationLogService invitationLogService;

    @Autowired
    private OmsOrderMapper omsOrderMapper;

    @Override
    public InvitationAnchor getEffectiveInvitationAnchor(String invitationCode) {
        LocalDateTime now = LocalDateTime.now();
        return this.lambdaQuery().eq(InvitationAnchor::getCode, invitationCode)
                .eq(InvitationAnchor::getStatus, 1)
                .eq(InvitationAnchor::getDeleteStatus, 0)
                .ge(InvitationAnchor::getStartTime, now)
                .le(InvitationAnchor::getEndTime, now)
                .gt(InvitationAnchor::getLimitCount, 0)
                .last("limit 1")
                .one();
    }

    @Override
    public CommonResult<String> generateInvitationAnchorCode(AnchorDto anchorDto, String userId) {
        try {
            QueryWrapper<InvitationAnchor> invitationAnchorQueryWrapper = new QueryWrapper<>();
            invitationAnchorQueryWrapper.eq("anchor_no", anchorDto.getAnchorNo());
            invitationAnchorQueryWrapper.eq("status", 1);
            List<InvitationAnchor> existInvitation = invitationAnchorMapper.selectList(invitationAnchorQueryWrapper);
            LocalDateTime start1 = LocalDateTime.parse(anchorDto.getStartTime(), DateTimeFormatter.ISO_LOCAL_DATE_TIME);
            LocalDateTime end1 = LocalDateTime.parse(anchorDto.getEndTime(), DateTimeFormatter.ISO_LOCAL_DATE_TIME);
            if (CollectionUtil.isNotEmpty(existInvitation)) {
                for (InvitationAnchor e : existInvitation) {
                    if (isLocalDateTimeIntersect(start1, end1, e.getStartTime(), e.getEndTime())) {
                        return CommonResult.failed("同一时段只能有一个编码");
                    }
                }

            }
            InvitationAnchor invitation = new InvitationAnchor();
            invitation.setStartTime(start1);
            invitation.setEndTime(end1);
            invitation.setCreateTime(LocalDateTime.now());
            invitation.setStatus(anchorDto.getStatus());
            invitation.setNeedNewUser(anchorDto.getNeedNewUser());
            invitation.setCreator(userId);
            invitation.setCode(anchorDto.getCode());
            invitation.setDiscount(anchorDto.getDiscount());
            invitation.setAnchorNo(anchorDto.getAnchorNo());
            invitation.setLimitCount(anchorDto.getLimitCount());
            invitationAnchorMapper.insert(invitation);
            return CommonResult.success(invitation.getCode());
        } catch (Exception e) {
            log.error("创建主播邀请码失败", e);
            return CommonResult.failed("创建主播邀请码失败 " + e.getMessage());
        }
    }

    @Override
    public CommonResult<String> updateInvitationAnchorCode(AnchorDto anchorDto) {
        if (Objects.isNull(anchorDto.getId())) {
            return CommonResult.failed("优惠码ID 不能为空");
        }
        InvitationAnchor invitationAnchor = invitationAnchorMapper.selectById(anchorDto.getId());
        if (Objects.isNull(invitationAnchor)) {
            return CommonResult.failed("优惠码不存在");
        }
        QueryWrapper<InvitationAnchor> invitationAnchorQueryWrapper = new QueryWrapper<>();
        invitationAnchorQueryWrapper.eq("anchor_no", anchorDto.getAnchorNo());
        invitationAnchorQueryWrapper.eq("status", 1);
        List<InvitationAnchor> existInvitation = invitationAnchorMapper.selectList(invitationAnchorQueryWrapper);
        LocalDateTime start1 = LocalDateTime.parse(anchorDto.getStartTime(), DateTimeFormatter.ISO_LOCAL_DATE_TIME);
        LocalDateTime end1 = LocalDateTime.parse(anchorDto.getEndTime(), DateTimeFormatter.ISO_LOCAL_DATE_TIME);
        if (CollectionUtil.isNotEmpty(existInvitation)) {
            for (InvitationAnchor e : existInvitation) {
                if (Objects.equals(e.getId(), anchorDto.getId())) {
                    continue;
                }
                if (isLocalDateTimeIntersect(start1, end1, e.getStartTime(), e.getEndTime())) {
                    return CommonResult.failed("同一时段只能有一个编码");
                }
            }

        }
        invitationAnchor.setAnchorNo(anchorDto.getAnchorNo());
        invitationAnchor.setStartTime(start1);
        invitationAnchor.setEndTime(end1);
        invitationAnchor.setDiscount(anchorDto.getDiscount());
        invitationAnchor.setLimitCount(anchorDto.getLimitCount());
        invitationAnchor.setAnchorNo(anchorDto.getAnchorNo());
        invitationAnchor.setNeedNewUser(anchorDto.getNeedNewUser());
        invitationAnchor.setStatus(anchorDto.getStatus());
        invitationAnchorMapper.updateById(invitationAnchor);
        return CommonResult.success(invitationAnchor.getCode());
    }

    public boolean isLocalDateTimeIntersect(LocalDateTime start1, LocalDateTime end1, LocalDateTime start2, LocalDateTime end2) {
        return !(start1.isAfter(end2) || start2.isAfter(end1));
    }

    @Override
    public CommonResult<String> validateCode(String invitationCode) {
        if (StringUtils.isBlank(invitationCode)) {
            return CommonResult.failed("validateCode:{} 参数不存在");
        }
        try {
            String formattedDateTime = getTimeString();
            QueryWrapper<InvitationAnchor> invitationAnchorQueryWrapper = new QueryWrapper<>();
            invitationAnchorQueryWrapper.eq("code", invitationCode);
            invitationAnchorQueryWrapper.eq("status", 1);
            invitationAnchorQueryWrapper.ge("start_time", formattedDateTime);
            invitationAnchorQueryWrapper.le("end_time", formattedDateTime);
            InvitationAnchor invitation = invitationAnchorMapper.selectOne(invitationAnchorQueryWrapper);
            if (Objects.isNull(invitation)) {
                return CommonResult.success("邀请码不存在或者未启用");
            }
            Long codeCount = orderManager.getCodeCount(invitation.getId());
            if (codeCount >= invitation.getLimitCount()) {
                return CommonResult.success("超过领取优惠码数量限制");
            }
            return CommonResult.success();
        } catch (Exception e) {
            return CommonResult.failed("请稍后重试");
        }
    }

    private String getTimeString() {
        LocalDateTime now = LocalDateTime.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        return now.format(formatter);
    }

    @Override
    public CommonResult<String> deleteCode(Long invitationCodeId) {
        UpdateWrapper<InvitationAnchor> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("id", invitationCodeId).set("delete_status", 1);
        if (!update(updateWrapper)) {
            return CommonResult.failed("删除失败");
        }
        ;
        return CommonResult.success();
    }

    @Override
    public CommonResult<String> enableCode(Long invitationCodeId, Integer enableStatus) {
        UpdateWrapper<InvitationAnchor> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("id", invitationCodeId).set("status", enableStatus);
        if (!update(updateWrapper)) {
            return CommonResult.failed("启停失败");
        }
        ;
        return CommonResult.success();
    }

    @Override
    public IPage<InvitationAnchorDetailResp> pageGameDiscountList(InvitationAnchorPageQuery invitationAnchorPageQuery) {
        // 创建分页对象
        Page page = new Page<>(invitationAnchorPageQuery.getPageNum(), invitationAnchorPageQuery.getPageSize());
        // 创建查询条件
        QueryWrapper<InvitationAnchor> queryWrapper = new QueryWrapper<>();
        if (StringUtils.isNotEmpty(invitationAnchorPageQuery.getAnchorNo())) {
            queryWrapper.like("anchor_no", invitationAnchorPageQuery.getAnchorNo());
        }
        if (StringUtils.isNotEmpty(invitationAnchorPageQuery.getCode())) {
            queryWrapper.eq("code", invitationAnchorPageQuery.getCode());
        }
        if (Objects.nonNull(invitationAnchorPageQuery.getStatus())) {
            queryWrapper.eq("status", invitationAnchorPageQuery.getStatus());
        }
        // 执行分页查询
        Page<InvitationAnchor> page1 = page(page, queryWrapper);
        // 将查询结果转换为UserDTO列表
        List<InvitationAnchorDetailResp> gameVos = page1.getRecords().stream()
                .map(game -> {
                    InvitationAnchorDetailResp gameVo = new InvitationAnchorDetailResp();
                    BeanUtil.copyProperties(game, gameVo);
                    return gameVo;
                })
                .collect(Collectors.toList());
        // 创建一个新的IPage对象，用于存储转换后的结果
        IPage<InvitationAnchorDetailResp> pmsProductCategoryIPage = new Page<>(invitationAnchorPageQuery.getPageNum(), invitationAnchorPageQuery.getPageSize(), page1.getTotal());
        pmsProductCategoryIPage.setRecords(gameVos);
        return pmsProductCategoryIPage;
    }

    @Override
    public CommonResult<InvitationAnchorDetailResp> getInvitationAnchorDetail(Long invitationCodeId) {
        InvitationAnchor invitationAnchor = invitationAnchorMapper.selectById(invitationCodeId);
        if (Objects.isNull(invitationAnchor)) {
            return CommonResult.failed("游戏优惠码不存在");
        }
        InvitationAnchorDetailResp resp = InvitationAnchorDetailRespMapping.INSTANCE.convertTo(invitationAnchor);
        resp.setGameOrderCountList(omsOrderMapper.selectGameOrderStatistics(InvitationTypeEnum.ANCHOR.getCode(), invitationAnchor.getCode()));
        return CommonResult.success(resp);
    }


    @Override
    public CommonPage<InvitationAnchorListResp> pageInvitationAnchor(InvitationAnchorPageQuery request) {
        PageHelper.startPage(request.getPageNum(), request.getPageSize());
        List<InvitationAnchor> invitationAnchorList = this.lambdaQuery()
                .like(StrUtil.isNotBlank(request.getAnchorNo()), InvitationAnchor::getAnchorNo, request.getAnchorNo())
                .eq(StrUtil.isNotBlank(request.getCode()), InvitationAnchor::getCode, request.getCode())
                .eq(Objects.nonNull(request.getStatus()), InvitationAnchor::getStatus, request.getStatus())
                .orderByDesc(InvitationAnchor::getCreateTime)
                .list();
        return CommonPage.restPageAndConvert(invitationAnchorList, InvitationAnchorListRespMapping.INSTANCE::convertTo);
    }
}
